﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CommonExtensions.ObjectExtensions;
using DBMigrator.Core.DBProviders;

namespace DBMigrator.Core.Execution
{
    public class VersionManager : IVersionManager
    {
        private const string VersionTableName = "SchemaVersion";
        private const string VersionColumnName = "Version";

        public bool IsVersionLoaded(DateTime version, IProvider provider)
        {
            if(version.IsNull())
                throw new ArgumentNullException("version");
            if(provider.IsNull())
                throw new ArgumentNullException("provider");

            if(!VersionTableExists(provider))
            {
                return false;
            }

            return provider.SelectCountFrom(VersionColumnName, VersionTableName,
                where => where.Column<DateTime>(VersionColumnName, c => c.IsEqualTo(version))) > 0;
        }

        public void AddVersion(DateTime version, IProvider provider)
        {
            if(version.IsNull())
                throw new ArgumentNullException("version");
            if(provider.IsNull())
                throw new ArgumentNullException("provider");

            CreateVersionTable(provider);
            provider.InsertInto(VersionTableName, new {Version = version});
        }

        public void RemoveVersion(DateTime version, IProvider provider)
        {
            if(version.IsNull())
                throw new ArgumentNullException("version");
            if(provider.IsNull())
                throw new ArgumentNullException("provider");
            if(!VersionTableExists(provider))
                throw new InvalidOperationException("Unable to remove version because version table does not exist");

            provider.DeleteFrom(VersionTableName,
                where => where.Column<DateTime>(VersionColumnName, c => c.IsEqualTo(version)));
        }

        private static bool VersionTableExists(IProvider provider)
        {
            return provider.DoesTableExist(VersionTableName);
        }

        private static void CreateVersionTable(IProvider provider)
        {
            if (!VersionTableExists(provider))
            {
                provider.CreateTable(VersionTableName, t => t.AddColumn<DateTime>("Version"));
            }
        }
    }
}
